local Screen = require "widgets/screen"
local TEMPLATES = require "widgets/redux/templates"
local Widget = require "widgets/widget"
local Text = require "widgets/text"
local Image = require "widgets/image"
local ImageButton = require "widgets/imagebutton"
local PopupDialogScreen = require "screens/redux/popupdialog"
local idata = require("QAQ/icondata")
local d_util = require "libs/datamanager"
local t_util = require "libs/tableutil"
local e_util = require "libs/entutil"

local function GetIconID(line)
    if type(line) == "table" then
        return tostring(line.altas)..tostring(line.image)
    end
    return "WrongID"
end

local MI = Class(Screen, function(self)
    Screen._ctor(self, "MoreMapIconSettings")

    
	self.bg = self:AddChild(TEMPLATES.BackgroundTint())
    self.root = self:AddChild(TEMPLATES.ScreenRoot())

    self.back_button = self.root:AddChild(TEMPLATES.BackButton(
		function()
			self:Close()
		end
	))
    self.title = self.root:AddChild(
		Text(
			HEADERFONT,
			30,
			"蘑菇慕斯 · 地图图标󰀜",
			UICOLOURS.GOLD_SELECTED
		)
	)
	self.title:SetPosition(0, 250)

    self.dialog = self.root:AddChild(TEMPLATES.RectangleWindow(736, 406))
	local r, g, b = unpack(UICOLOURS.BROWN_DARK)
	self.dialog:SetBackgroundTint(r, g, b, 0.8)
	self.dialog:SetPosition(0, -5)
	-- self.dialog.top:Hide()

    local tmip_path = resolvefilepath("images/customicobyysh.xml")
    local minimap_path = resolvefilepath("minimap/minimap_data.xml")

    local function delete_icon_data()
        local w_data = require("libs/worldmanager"):GetWorldDataList("more_map_icons")
        local d = self.temp_data and self.temp_data.d
        for w_id, data in pairs(w_data)do
            local info = data.atlas and data.image and data
                if not info then
                    if data.p then
                        local image = data.p..".tex"
                        local inv_altas = GetInventoryItemAtlas(image)
                        info = idata[data.p]
                        if info and TheSim:AtlasContains(resolvefilepath(info.atlas), info.image) then
                        elseif TheSim:AtlasContains(tmip_path, image) then
                            info = {atlas= tmip_path, image = image}
                        elseif TheSim:AtlasContains(minimap_path, image) then
                            info = {atlas= minimap_path, image = image}
                        elseif inv_altas and TheSim:AtlasContains(inv_altas, image)  then
                            info = {atlas= inv_altas,image = image}
                        end
                    end
                end
            if info then
                local a = info.atlas
                local i = info.image
                for _, line in pairs(d)do
                    if type(line)=="table" and line.altas == a and line.image == i then
                        w_data[w_id] = nil
                        break
                    end
                end
            end
        end
        
        self.temp_data.d = {}
    end

    local function hide_icon_data()
        local h_data = self.temp_data.h
        local n_data = {}
        for _, line in pairs(h_data)do
            if type(line) == "table" then
                table.insert(n_data, {
                    a = line.altas,
                    i = line.image
                })
            end
        end
        require("libs/settingmanager"):SaveSettingList("hide_more_map_icons", n_data)
        MOD_ShroomCake.Setting.hide_more_map_icon = n_data
    end

    self.savebtn = self.root:AddChild(TEMPLATES.StandardButton(function()
        local d = self.temp_data and self.temp_data.d
        if d then
            local candelete
            for _, checked in pairs(d)do
                if checked then
                    candelete = true
                    break
                end
            end
            if candelete then
                local pds = PopupDialogScreen("蘑菇慕斯 · 提示󰀜", 
                    "你确定要删除选定的图标记录吗？此操作不可撤销！\n 如需禁用同类图标显示，请勾选【不再显示】\n 另外，虫洞标记和刷新点预测 的部分修改需要游戏重新加载才能生效",{
                        {
                            text = "取消",
                            cb = function()
                                TheFrontEnd:PopScreen()
                            end
                        },{
                            text = "确定删除！",
                            cb = function()
                                hide_icon_data()
                                delete_icon_data()
                                self:BuildWindow()
                                TheFrontEnd:PopScreen()
                            end
                        }
                    }, nil, nil, "dark_wide")
                TheFrontEnd:PushScreen(pds)
            else
                hide_icon_data()
                self:Close()
            end
        end
	end, "保存设置", {200, 60}))
	self.savebtn:SetPosition(290, -240)

    local function showtipandreturn(tip)
        local pds = PopupDialogScreen("定位天体 · 提示󰀜", 
                tip,{
                    {
                        text = "我知道了",
                        cb = function()
                            TheFrontEnd:PopScreen()
                            self:Close()
                        end
                    },
                }, nil, nil, "dark_wide")
        return TheFrontEnd:PushScreen(pds)
    end

    self.alterbtn = self.root:AddChild(TEMPLATES.StandardButton(function()

        local w_data = require("libs/worldmanager"):GetWorldDataList("more_map_icons")
        for w_id, data in pairs(w_data)do
            if type(data)=="table" and data.image == "huxi_archive_resonator.tex" then
                w_data[w_id] = nil
            end
        end

        local arrows = e_util:FindEnts(nil, {"archive_resonator_base", "medal_resonator_base"}, nil, nil, {"huxi"})
        if #arrows == 0 then
            return showtipandreturn("定位标记不足, 请放置星象探测仪或寻宝装置\n需要一个屏幕的范围内有两个箭头标记")
        elseif #arrows < 2 then
            return showtipandreturn("定位标记不足, 请继续放置星象探测仪或寻宝装置\n需要一个屏幕的范围内有两个箭头标记")
        else
            local a1,a2 = arrows[1], arrows[2]
            if e_util:IsValid(a1) and e_util:IsValid(a2) then
                local r1 = a1:GetRotation()+90
                local r2 = a2:GetRotation()+90
                local rad1 = -math.rad(r1)
                local rad2 = -math.rad(r2)
                local m1 = math.tan(rad1)
                local m2 = math.tan(rad2)
                if m1 == m2 then
                    return showtipandreturn("两个定位标记平行，无法判断\n请重新放置星象探测仪或寻宝装置")
                end
                local x1, _, y1 = a1.Transform:GetWorldPosition()
                local x2, _, y2 = a2.Transform:GetWorldPosition()
                local c1 = y1 - m1 * x1
                local c2 = y2 - m2 * x2
                local x = (c2 - c1) / (m1 - m2)
                local y = m1 * x + c1
                x = string.format("%.2f", x)
                y = string.format("%.2f", y)
                table.insert(w_data, {
                    c = TheWorld:HasTag("cave") and 1 or 0,
                    x = x,
                    z = y,
                    p = "huxi_archive_resonator",
                    l = 0,
                    atlas = "images/shroomcake_moreicons.xml",
                    image = "huxi_archive_resonator.tex",
                    m = 0,      -- 拥有此标记时，将扫面该点附近的"huxi"标签并重新设立位置
                })
                TheFocalPoint.SoundEmitter:PlaySound("dontstarve/HUD/Together_HUD/learn_map")
                ThePlayer.HUD.controls:ShowMap(Vector3(x, 0, y))
                self:Close()
            else
                return showtipandreturn("定位标记不是真实实体，请重新放置星象探测仪或寻宝装置")
            end
        end
    end, "定位天体", {200, 60}))
    self.alterbtn:SetPosition(0, -240)
    
    self.nodata = self.root:AddChild(Text(HEADERFONT, 35, "没有可以设置的图标，再探索世界看看吧！"))
    
    self.temp_data = {h = {}, d = {}}
    local h_data = self.temp_data.h
    local s_data = d_util:GetIconData()
    for _, line in pairs(s_data)do
        local n_data = {altas = line.a, image = line.i}
        h_data[GetIconID(n_data)] = n_data
    end
    self:BuildWindow()
end)

local function GetIconData()
    local result = {}
    local w_data = require("libs/worldmanager"):GetWorldDataList("more_map_icons")
    local h_data = d_util:GetIconData()
    

    for _, info in pairs(h_data)do
        table.insert(result, {
            count = 0,
            altas = info.a,
            image = info.i,
        })
    end
    for _, data in pairs(w_data)do
        local info = (data.atlas and data.image and data) or (data.p and idata[data.p])
        if info then
            local a = info.atlas
            local i = info.image
            local has
            for _, line in pairs(result)do
                if line.altas == a and line.image == i then
                    line.count = line.count and line.count+1 or 1
                    has = true
                    break
                end
            end
            if not has then
                table.insert(result, {
                    count = 1,
                    altas = a,
                    image = i
                })
            end
        end
    end
    table.sort(result, function(a, b)
        return a.count > b.count
    end)
    return result
end

local d_tex = "greenmooneye.tex"
local d_xml = GetInventoryItemAtlas(d_tex)
function MI:BuildWindow()
    local icons_data = GetIconData()
    
    
    local function scrollWidgetCtorFn(context, index)
		local w = Widget("")
		w:SetPosition(10, 0)

        local bg = w:AddChild(Image("images/frontend_redux.xml", "listitem_thick_normal.tex"))
        bg:ScaleToSize(235, 120)
        local hover_overlay = bg:AddChild(Image("images/frontend_redux.xml", "listitem_thick_hover.tex"))
        bg:SetOnGainFocus(function() bg:SetTint(1,1,1,0.7) hover_overlay:Show() end)
        bg:SetOnLoseFocus(function(self) bg:SetTint(1,1,1,0.5) hover_overlay:Hide() end)
        bg.onlosefocusfn()

		w.hideit = w:AddChild(TEMPLATES.LabelCheckbox(nil, nil, "不再显示"))
        w.hideit:SetPosition(15, 5)
        
		w.deleteit = w:AddChild(TEMPLATES.LabelCheckbox(nil, nil, "删除记录"))
        w.deleteit:SetPosition(15, -30)


		w.img = w:AddChild(Image(d_xml, d_tex))
        w.img:ScaleToSize(70, 70)
		w.img:SetPosition(-55, 0)


		w.count = w:AddChild(Text(NEWFONT_SMALL,18))
		w.count:SetPosition(60, 40)
		return w
	end

    local function scrollWidgetApplyFn(context, w, data, index)
		if not data then return w:Hide() end

        local data_id = GetIconID(data)
        -- 这一步是为了适配旧版慕斯，虽然降低效率，但不可删除
        if type(data.altas)=="string" and data.altas:match("mod_boss")then
            data.altas = "images/shroomcake_moreicons.xml"
        end
		w.img:SetTexture(data.altas, data.image)
		w.count:SetString("共 "..data.count.." 个")
        local function clickIt(btn, id)
            btn.checked = not btn.checked
            self.temp_data[id][data_id] = btn.checked and data
            btn:Refresh()
        end
        w.hideit:SetOnClick(function()
            clickIt(w.hideit, "h")
        end)
        w.deleteit:SetOnClick(function()
            clickIt(w.deleteit, "d")
        end)
        w.hideit.checked = self.temp_data.h[data_id]
        w.deleteit.checked = self.temp_data.d[data_id]
        w.hideit:Refresh()
        w.deleteit:Refresh()

		w:Show()
	end
    if self.grid then
		self.grid:Kill()
	end
    self.grid = self.root:AddChild(TEMPLATES.ScrollingGrid(
		{},
		{
			context = {},
			item_ctor_fn = scrollWidgetCtorFn,
			apply_fn = scrollWidgetApplyFn,
			widget_width = 245,
			widget_height = 130,
			num_visible_rows = 3,
			num_columns = 3,
			scrollbar_offset = 0,
			scrollbar_height_offset = -70,
			scroll_per_click = 0.5,
			scissor_pad = 16,
			peek_percent = 0,
			allow_bottom_empty_row = true,
		}
	))
	self.grid:SetPosition(-10, 5)
    if next(icons_data) then
        self.grid:SetItemsData(icons_data)
        self.nodata:Hide()
    end
end

function MI:OnControl(control, down)
	if self._base.OnControl(self, control, down) then
		return true
	end
	if not down and control == CONTROL_CANCEL then
		return self:Close()
	end
end

function MI:Close()
	TheFrontEnd:PopScreen(self)
end

return MI